/**
 * 全局错误处理中间件
 * 统一处理应用中的各种错误，特别是文本更新相关错误
 */

import errorMonitoring from './errorMonitoring.js'
import lifecycleManager from './componentLifecycle.js'
import textUpdateSafe from './textUpdateSafe.js'

class GlobalErrorHandler {
  constructor() {
    this.isInitialized = false
    this.errorHandlers = new Map()
    this.errorQueue = []
    this.isProcessingQueue = false
    this._wxErrorHandlerSet = false
    
    // 错误统计
    this.errorStats = {
      total: 0,
      textUpdate: 0,
      network: 0,
      component: 0,
      unknown: 0
    }
  }

  /**
   * 初始化全局错误处理
   */
  init() {
    if (this.isInitialized) return
    
    console.log('初始化全局错误处理中间件')
    
    // 设置Vue错误处理
    this.setupVueErrorHandling()
    
    // 设置微信小程序错误处理
    this.setupMiniProgramErrorHandling()
    
    // 设置Promise错误处理
    this.setupPromiseErrorHandling()
    
    // 设置自定义错误处理器
    this.setupCustomErrorHandlers()
    
    // 启动错误队列处理
    this.startErrorQueueProcessing()
    
    this.isInitialized = true
    console.log('全局错误处理中间件初始化完成')
  }

  /**
   * 设置Vue错误处理
   */
  setupVueErrorHandling() {
    // Vue全局错误处理
    if (typeof Vue !== 'undefined') {
      Vue.config.errorHandler = (error, vm, info) => {
        this.handleError('VUE_ERROR', error, {
          component: vm,
          info,
          componentId: vm ? textUpdateSafe.getComponentId(vm) : null
        })
      }

      // Vue警告处理
      Vue.config.warnHandler = (msg, vm, trace) => {
        this.handleWarning('VUE_WARNING', msg, {
          component: vm,
          trace,
          componentId: vm ? textUpdateSafe.getComponentId(vm) : null
        })
      }
    }

    // 全局JavaScript错误
    if (typeof window !== 'undefined') {
      window.addEventListener('error', (event) => {
        this.handleError('JS_ERROR', event.error || new Error(event.message), {
          filename: event.filename,
          lineno: event.lineno,
          colno: event.colno,
          source: 'window_error'
        })
      })

      // 资源加载错误
      window.addEventListener('error', (event) => {
        if (event.target !== window) {
          this.handleError('RESOURCE_ERROR', new Error(`资源加载失败: ${event.target.src || event.target.href}`), {
            element: event.target.tagName,
            source: event.target.src || event.target.href
          })
        }
      }, true)
    }
  }

  /**
   * 设置微信小程序错误处理
   */
  setupMiniProgramErrorHandling() {
    // 避免重复设置微信小程序错误处理
    if (typeof wx !== 'undefined' && wx.onError && !this._wxErrorHandlerSet) {
      this._wxErrorHandlerSet = true
      
      wx.onError((error) => {
        // 忽略函数定义被当作错误的情况
        if (typeof error === 'string' && (
          error.includes('function (error)') || 
          error.includes('function(error)') ||
          error.includes('_this.logError') ||
          error.includes('_this2.handleError')
        )) {
          return
        }
        
        // 检查是否为32776错误
        if (typeof error === 'string' && error.includes('32776')) {
          this.handleTextUpdateError(error)
        } else {
          this.handleError('MP_ERROR', new Error(error), {
            source: 'miniprogram_global'
          })
        }
      })
    }

    // 微信小程序未处理的Promise拒绝
    if (typeof wx !== 'undefined' && wx.onUnhandledRejection) {
      wx.onUnhandledRejection((event) => {
        this.handleError('MP_UNHANDLED_REJECTION', event.reason, {
          source: 'miniprogram_promise'
        })
      })
    }
  }

  /**
   * 设置Promise错误处理
   */
  setupPromiseErrorHandling() {
    if (typeof window !== 'undefined') {
      window.addEventListener('unhandledrejection', (event) => {
        this.handleError('UNHANDLED_PROMISE_REJECTION', event.reason, {
          source: 'promise_rejection'
        })
      })
    }
  }

  /**
   * 设置自定义错误处理器
   */
  setupCustomErrorHandlers() {
    // 文本更新错误处理器
    this.addErrorHandler('TEXT_UPDATE_32776', (error, context) => {
      return this.handleTextUpdate32776Error(error, context)
    })

    // 组件销毁错误处理器
    this.addErrorHandler('COMPONENT_DESTROYED', (error, context) => {
      return this.handleComponentDestroyedError(error, context)
    })

    // 网络错误处理器
    this.addErrorHandler('NETWORK_ERROR', (error, context) => {
      return this.handleNetworkError(error, context)
    })

    // 数据绑定错误处理器
    this.addErrorHandler('DATA_BINDING_ERROR', (error, context) => {
      return this.handleDataBindingError(error, context)
    })
  }

  /**
   * 启动错误队列处理
   */
  startErrorQueueProcessing() {
    setInterval(() => {
      this.processErrorQueue()
    }, 1000) // 每秒处理一次错误队列
  }

  /**
   * 处理错误
   * @param {string} type - 错误类型
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   */
  handleError(type, error, context = {}) {
    try {
      // 更新统计
      this.updateErrorStats(type)

      // 创建错误记录
      const errorRecord = {
        id: this.generateErrorId(),
        type,
        error,
        context: {
          ...context,
          timestamp: Date.now(),
          userAgent: this.getUserAgent(),
          platform: this.getPlatform()
        },
        handled: false
      }

      // 添加到错误队列
      this.errorQueue.push(errorRecord)

      // 记录到错误监控系统
      errorMonitoring.logTextUpdateError(type, error, errorRecord.context)

      // 立即处理关键错误
      if (this.isCriticalError(type)) {
        this.processErrorRecord(errorRecord)
      }

      console.error(`[GlobalErrorHandler] ${type}:`, error, context)

    } catch (handlingError) {
      console.error('处理错误时发生异常:', handlingError)
    }
  }

  /**
   * 处理警告
   * @param {string} type - 警告类型
   * @param {string} message - 警告消息
   * @param {Object} context - 警告上下文
   */
  handleWarning(type, message, context = {}) {
    console.warn(`[GlobalErrorHandler] ${type}:`, message, context)
    
    // 某些警告可能预示着即将发生的错误
    if (this.isWarningCritical(type, message)) {
      this.handleError(`${type}_CRITICAL`, new Error(message), context)
    }
  }

  /**
   * 处理文本更新错误
   * @param {string} errorMessage - 错误消息
   */
  handleTextUpdateError(errorMessage) {
    const error = new Error(errorMessage)
    
    // 尝试从错误消息中提取组件信息
    const context = this.extractContextFromError(errorMessage)
    
    this.handleError('TEXT_UPDATE_32776', error, context)
  }

  /**
   * 处理32776文本更新错误
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   */
  async handleTextUpdate32776Error(error, context) {
    try {
      console.log('处理32776文本更新错误')

      // 如果有组件ID，检查组件状态
      if (context.componentId) {
        if (lifecycleManager.isDestroyed(context.componentId)) {
          console.log('组件已销毁，忽略32776错误')
          return true
        }
      }

      // 尝试清理可能的DOM状态
      await this.cleanupDOMState()

      // 如果有重试回调，延迟执行
      if (context.retryCallback) {
        setTimeout(async () => {
          try {
            await context.retryCallback()
            console.log('32776错误重试成功')
          } catch (retryError) {
            console.error('32776错误重试失败:', retryError)
          }
        }, 100)
      }

      return true
    } catch (error) {
      console.error('处理32776错误失败:', error)
      return false
    }
  }

  /**
   * 处理组件销毁错误
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   */
  handleComponentDestroyedError(error, context) {
    console.log('处理组件销毁错误')
    
    // 清理相关资源
    if (context.componentId) {
      lifecycleManager.markDestroyed(context.componentId)
    }
    
    return true
  }

  /**
   * 处理网络错误
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   */
  async handleNetworkError(error, context) {
    console.log('处理网络错误')
    
    // 检查网络状态
    const isOnline = await this.checkNetworkStatus()
    if (!isOnline) {
      this.showNetworkErrorTip()
      return false
    }
    
    // 如果有重试回调，执行重试
    if (context.retryCallback) {
      setTimeout(context.retryCallback, 2000)
    }
    
    return true
  }

  /**
   * 处理数据绑定错误
   * @param {Error} error - 错误对象
   * @param {Object} context - 错误上下文
   */
  handleDataBindingError(error, context) {
    console.log('处理数据绑定错误')
    
    // 检查组件状态
    if (context.componentId && lifecycleManager.isDestroyed(context.componentId)) {
      return true // 组件已销毁，忽略错误
    }
    
    // 尝试重新绑定数据
    if (context.component && context.data) {
      setTimeout(() => {
        textUpdateSafe.safeUpdate(context.component, context.data)
          .catch(retryError => {
            console.error('数据绑定重试失败:', retryError)
          })
      }, 50)
    }
    
    return true
  }

  /**
   * 处理错误队列
   */
  async processErrorQueue() {
    if (this.isProcessingQueue || this.errorQueue.length === 0) return
    
    this.isProcessingQueue = true
    
    try {
      const errorsToProcess = this.errorQueue.splice(0, 10) // 每次处理最多10个错误
      
      for (const errorRecord of errorsToProcess) {
        if (!errorRecord.handled) {
          await this.processErrorRecord(errorRecord)
        }
      }
    } finally {
      this.isProcessingQueue = false
    }
  }

  /**
   * 处理单个错误记录
   * @param {Object} errorRecord - 错误记录
   */
  async processErrorRecord(errorRecord) {
    try {
      const handler = this.errorHandlers.get(errorRecord.type)
      if (handler) {
        const handled = await handler(errorRecord.error, errorRecord.context)
        errorRecord.handled = handled
      } else {
        console.warn(`没有找到错误类型 ${errorRecord.type} 的处理器`)
        errorRecord.handled = true // 标记为已处理，避免重复处理
      }
    } catch (error) {
      console.error('处理错误记录失败:', error)
      errorRecord.handled = true
    }
  }

  /**
   * 添加错误处理器
   * @param {string} type - 错误类型
   * @param {Function} handler - 处理函数
   */
  addErrorHandler(type, handler) {
    this.errorHandlers.set(type, handler)
  }

  /**
   * 移除错误处理器
   * @param {string} type - 错误类型
   */
  removeErrorHandler(type) {
    this.errorHandlers.delete(type)
  }

  /**
   * 更新错误统计
   * @param {string} type - 错误类型
   */
  updateErrorStats(type) {
    this.errorStats.total++
    
    if (type.includes('TEXT_UPDATE') || type.includes('32776')) {
      this.errorStats.textUpdate++
    } else if (type.includes('NETWORK')) {
      this.errorStats.network++
    } else if (type.includes('COMPONENT')) {
      this.errorStats.component++
    } else {
      this.errorStats.unknown++
    }
  }

  /**
   * 检查是否为关键错误
   * @param {string} type - 错误类型
   * @returns {boolean}
   */
  isCriticalError(type) {
    const criticalTypes = [
      'TEXT_UPDATE_32776',
      'COMPONENT_DESTROYED',
      'VUE_ERROR'
    ]
    return criticalTypes.includes(type)
  }

  /**
   * 检查警告是否关键
   * @param {string} type - 警告类型
   * @param {string} message - 警告消息
   * @returns {boolean}
   */
  isWarningCritical(type, message) {
    return message.includes('32776') || 
           message.includes('updateTextView') ||
           message.includes('destroyed')
  }

  /**
   * 从错误消息中提取上下文
   * @param {string} errorMessage - 错误消息
   * @returns {Object}
   */
  extractContextFromError(errorMessage) {
    const context = {}
    
    // 尝试提取组件ID
    const componentMatch = errorMessage.match(/component[_\s]+(\w+)/i)
    if (componentMatch) {
      context.extractedComponentId = componentMatch[1]
    }
    
    // 尝试提取元素ID
    const elementMatch = errorMessage.match(/element[_\s]+(\w+)/i)
    if (elementMatch) {
      context.extractedElementId = elementMatch[1]
    }
    
    return context
  }

  /**
   * 清理DOM状态
   */
  async cleanupDOMState() {
    // 等待下一个事件循环
    await new Promise(resolve => setTimeout(resolve, 0))
    
    // 强制垃圾回收（如果支持）
    if (typeof wx !== 'undefined' && wx.triggerGC) {
      wx.triggerGC()
    }
  }

  /**
   * 检查网络状态
   * @returns {Promise<boolean>}
   */
  checkNetworkStatus() {
    return new Promise(resolve => {
      if (typeof wx !== 'undefined' && wx.getNetworkType) {
        wx.getNetworkType({
          success: (res) => resolve(res.networkType !== 'none'),
          fail: () => resolve(true)
        })
      } else if (typeof navigator !== 'undefined') {
        resolve(navigator.onLine)
      } else {
        resolve(true)
      }
    })
  }

  /**
   * 显示网络错误提示
   */
  showNetworkErrorTip() {
    try {
      uni.showToast({
        title: '网络连接异常，请检查网络设置',
        icon: 'none',
        duration: 3000
      })
    } catch (error) {
      console.error('显示网络错误提示失败:', error)
    }
  }

  /**
   * 生成错误ID
   * @returns {string}
   */
  generateErrorId() {
    return `global_error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 获取用户代理
   * @returns {string}
   */
  getUserAgent() {
    if (typeof navigator !== 'undefined') {
      return navigator.userAgent
    }
    return 'WeChat MiniProgram'
  }

  /**
   * 获取平台信息
   * @returns {string}
   */
  getPlatform() {
    // #ifdef MP-WEIXIN
    return 'miniprogram'
    // #endif
    
    // #ifdef H5
    return 'h5'
    // #endif
    
    return 'unknown'
  }

  /**
   * 获取错误统计
   * @returns {Object}
   */
  getErrorStats() {
    return { ...this.errorStats }
  }

  /**
   * 重置错误统计
   */
  resetErrorStats() {
    this.errorStats = {
      total: 0,
      textUpdate: 0,
      network: 0,
      component: 0,
      unknown: 0
    }
  }

  /**
   * 销毁错误处理器
   */
  destroy() {
    this.errorHandlers.clear()
    this.errorQueue = []
    this.isInitialized = false
    console.log('全局错误处理中间件已销毁')
  }
}

// 创建全局实例
const globalErrorHandler = new GlobalErrorHandler()

// 自动初始化
globalErrorHandler.init()

export default globalErrorHandler